<?php

namespace app\xs_test\service;

use app\xs_test\enum\OrderSnKeyEnum;
use app\xs_test\facade\service\GoodsServiceFacade;
use app\xs_test\facade\service\MemberCartServiceFacade;
use app\xs_test\facade\service\OrderGoodsServiceFacade;
use app\xs_test\facade\service\OrderServiceFacade;
use xsframe\base\BaseService;
use xsframe\exception\ApiException;
use xsframe\util\PriceUtil;
use xsframe\util\RandomUtil;
use think\facade\Db;

class OrderService extends BaseService
{
    protected $tableName = "xs_test_shop_order";

    /**
     * @param $userId
     * @param $id
     * @param int $total
     * @param int $addressId
     * @param int $cartIds
     * @param string $remark
     * @return string
     * @throws ApiException
     */
    public function create($userId, $id, int $total = 1, int $addressId = 0, int $cartIds = 0, string $remark = ''): string
    {
        try {
            $ordersn = $this->createGoods($userId, $id, $total, $addressId, $cartIds, $remark);
        } catch (ApiException $e) {
            throw new ApiException($e->msg);
        }
        return $ordersn;
    }

    /**
     * 获取订单列表
     * @param $condition
     * @return mixed
     */
    public function getOrderList($condition)
    {
        $orderList = OrderServiceFacade::getAll($condition, "*", "id desc");

        foreach ($orderList as &$item) {
            $item['createtime'] = date('Y-m-d H:i:s', $item['createtime']);
            $item['status_val'] = $this->getStatusVal($item['status'], $item['service_type']);

            $orderGoodsList = OrderGoodsServiceFacade::getAll(['orderid' => $item['id']]);
            $orderGoodsList = GoodsServiceFacade::listMergeGoodsInfo($orderGoodsList, 'goodsid');

            $orderGoodsTotal = 0;
            foreach ($orderGoodsList as $og) {
                $orderGoodsTotal = $orderGoodsTotal + $og['total'];
            }
            unset($og);

            $item['orderGoods'] = $orderGoodsList;
            $item['orderTotal'] = $orderGoodsTotal;
        }
        unset($item);
        return $orderList;
    }

    /**
     * 获取订单基本信息
     * @param $userId
     * @param $ordersn
     * @return mixed
     * @throws ApiException
     */
    public function getOrderInfo($userId, $ordersn)
    {
        $orderInfo = OrderServiceFacade::getInfo(['ordersn' => $ordersn, 'mid' => $userId]);

        if (!empty($orderInfo)) {
            $orderInfo['paytime'] = date('Y-m-d H:i:s', $orderInfo['paytime']);
            $orderInfo['createtime'] = date('Y-m-d H:i:s', $orderInfo['createtime']);

            $orderInfo['status_val'] = $this->getStatusVal($orderInfo['status'], $orderInfo['service_type']);
            $orderInfo['paytype_val'] = $this->getPayTypeVal($orderInfo['paytype']);

            $orderGoodsList = OrderGoodsServiceFacade::getAll(['orderid' => $orderInfo['id']]);
            $orderGoodsList = GoodsServiceFacade::listMergeGoodsInfo($orderGoodsList, 'goodsid');

            $orderGoodsTotal = 0;
            foreach ($orderGoodsList as $og) {
                $orderGoodsTotal = $orderGoodsTotal + $og['total'];
            }
            unset($og);

            $orderInfo['orderGoods'] = $orderGoodsList;
            $orderInfo['orderTotal'] = $orderGoodsTotal;
            $orderInfo['title'] = count($orderGoodsList) > 1 ? "合并支付订单" : $orderGoodsList[0]['goods']['title'];
        } else {
            throw new ApiException("订单不存在");
        }

        return $orderInfo;
    }

    /**
     * 订单支付成功回调
     * @param $orderId
     * @param $serviceType
     * @return bool
     */
    public function payResult($orderId, $serviceType)
    {
        return $this->buyGoods($orderId);
    }

    /**
     * 创建商品订单
     * @param $userId
     * @param $goodsId
     * @param int $total
     * @param int $addressId
     * @param int $cartIds
     * @param string $remark
     * @return string
     * @throws ApiException
     */
    private function createGoods($userId, $goodsId, $total = 1, $addressId = 0, $cartIds = null, $remark = '')
    {
        $sumPrice = 0.00;

        if (empty($cartIds)) {
            $goodsList = GoodsServiceFacade::getAll(['id' => $goodsId], "id,title,thumb,marketprice,unit,total");
        } else {
            $cartList = MemberCartServiceFacade::getAll(['id' => explode(",", $cartIds), 'mid' => $userId, 'deleted' => 0], "id,goodsid,optionid,total", "createtime desc", "goodsid");
            $goodsList = GoodsServiceFacade::getAll(['id' => array_column($cartList, 'goodsid')], "id,title,thumb,marketprice,unit,total", "createtime desc", "id");
        }

        if (empty($goodsList)) {
            throw new ApiException("下单商品不存在");
        }

        foreach ($goodsList as $goodsInfo) {
            if (!empty($cartIds)) {
                $total = $cartList[$goodsInfo['id']]['total'];
            }
            $sumPrice = $sumPrice + PriceUtil::numberFormat($goodsInfo['marketprice'] * $total);
        }

        if ($sumPrice <= 0) {
            throw new ApiException("支付金额不能为0");
        }

        if (empty($addressId)) {
            throw new ApiException("请填写收货地址");
        }

        // 启动事务
        Db::startTrans();
        try {
            $ordersn = OrderSnKeyEnum::GOODS_CODE . date("Ymd") . RandomUtil::random(12, true);
            $orderData = [
                'uniacid'      => $this->uniacid,
                'mid'          => $userId,
                'ordersn'      => $ordersn,
                'price'        => $sumPrice,
                'service_type' => 1,
                'createtime'   => time(),
                'remark'       => $remark,
            ];
            $orderData['oldprice'] = $orderData['price'];

            $orderId = OrderServiceFacade::insertInfo($orderData);

            // 清购物车商品
            if (!empty($cartIds)) {
                MemberCartServiceFacade::updateInfo(['deleted' => 1], ['id' => explode(",", $cartIds)]);
            }

            foreach ($goodsList as $goodsInfo) {
                if (!empty($cartIds)) {
                    $total = $cartList[$goodsInfo['id']]['total'];
                }

                $orderGoodsData = [
                    'uniacid'    => $this->uniacid,
                    'mid'        => $userId,
                    'orderid'    => $orderId,
                    'goodsid'    => $goodsInfo['id'],
                    'optionid'   => 0,
                    'price'      => PriceUtil::numberFormat($goodsInfo['marketprice'] * $total),
                    'total'      => $total,
                    'createtime' => time(),
                ];
                $orderGoodsData['oldprice'] = $orderGoodsData['price'];
                OrderGoodsServiceFacade::insertInfo($orderGoodsData);

                # 锁库存操作 TODO
                if ($goodsInfo['total'] >= 0) {
                    if ($goodsInfo['total'] >= $total) {
                        GoodsServiceFacade::updateInfo(['total' => Db::raw('total - ' . $total)], ['id' => $goodsInfo['id']]);
                    } else {
                        throw new ApiException("“{$goodsInfo['title']}”库存不足");
                    }
                }
            }

            // 提交事务
            Db::commit();
        } catch (\Exception $e) {
            // 回滚事务
            Db::rollback();
        }

        return $ordersn;
    }

    /**
     * 获取支付类型
     * @param string $payType
     * @return string
     */
    private function getPayTypeVal(string $payType = ''): string
    {
        switch ($payType) {
            case 0:
                $typeVal = '未支付';
                break;
            case 1:
                $typeVal = '微信支付';
                break;
            case 2:
                $typeVal = '支付宝支付';
                break;
            case 3:
                $typeVal = '余额支付';
                break;
            case 4:
                $typeVal = '后台支付';
                break;
            default:
                $typeVal = '未支付';
        }
        return $typeVal;
    }

    /**
     * 获取订单状态
     * @param $status
     * @param int $serviceType
     * @return string
     */
    private function getStatusVal($status, int $serviceType = 1): string
    {
        // 支付状态 0未支付 1已支付(待发货) 2已发货(待收货) 3已完成 4退款中 5已退款 -1已关闭
        switch ($status) {
            case 0:
                $statusVal = '未支付';
                break;
            case 1:
                $statusVal = $serviceType == 1 ? '待发货' : '已支付';
                break;
            case 2:
                $statusVal = '已发货';
                break;
            case 3:
                $statusVal = '已完成';
                break;
            case 4:
                $statusVal = '退款中';
                break;
            case 5:
                $statusVal = '已退款';
                break;
            case -1:
                $statusVal = '已关闭';
                break;
            default:
                $statusVal = '';
        }
        return $statusVal;
    }

    /**
     * 购买商品成功
     * @param $orderId
     * @return bool
     */
    private function buyGoods($orderId): bool
    {
        return true;
    }
}